<!--Echarts 2D地图+高德API 生成地图-->
<template>
    <div class="content">
        <div class="chart-div" ref="chartRef"></div>
        <div class="mapChoose">
           <span v-for="(item, index) in parentInfo" :key="item.code">
            <button class="button type1" @click="chooseArea(item, index)">
             {{ item.cityName == "全国" ? "中国" : item.cityName }}
            </button>
            <span class="iconfont icon-xiayige" v-show="index + 1 != parentInfo.length"></span>
           </span>
        </div>
        <div class="content-title">
            <span>Echarts 2D地图+高德API 生成地图</span>
        </div>
    </div>
</template>

<script setup>
    import { ref,inject,onMounted} from 'vue';

    import * as echarts from "echarts";


    // 获取地图DOM元素
    const chartRef = ref();
    const mapChart = ref();
    const geoJson = ref({
        features:[],
    });
    const parentInfo = ref([
        {
            //地图列表（默认为全国-中国）
            cityName: "全国", //
            code: 100000, //全国的区划编码
        },
    ])

    /**
     * @description 根据区划编码调用高德api获取地理信息
     * @param {number} adcode 区划编码
     */
    const getGeoJson = (adcode) =>{
        let that = this;
        // 高德api获取初始化地理信息，详情可查看 https://lbs.amap.com/api/amap-ui/reference-amap-ui/geo/district-explorer
        // DistrictExplorer（行政区划浏览） 提供了全国范围内到区县一级的行政区划数据（含边界）
        AMapUI.loadUI(["geo/DistrictExplorer"], (DistrictExplorer) => {
            var districtExplorer = new DistrictExplorer();
            districtExplorer.loadAreaNode(adcode, function (error, areaNode) {
                // 错误信息 - error
                if (error) {
                    console.error(error);
                    return;
                }

                // 区域节点 - AreaNode
                // getSubFeatures() 返回该区域中全部的子级区划Feature数组
                let Json = areaNode.getSubFeatures();
                // 存在子级区域时，直接赋值
                if (Json.length > 0) {
                    geoJson.value.features = Json;
                } else if (Json.length === 0) {
                    // 不存在子级区域时，在原数组中筛选自己本身
                    geoJson.value.features = geoJson.value.features.filter(
                        (item) => item.properties.adcode == adcode
                    );
                    if (geoJson.value.features.length === 0) return;
                }
               getMapData();
            });
        });
    };
    /**
     * @description 获取并整理形成需要的数据
     */
    const getMapData = () =>{
        let mapData = geoJson.value.features.map((item) => {
            return {
                name: item.properties.name,
                value: Math.random() * 1000,
                cityCode: item.properties.adcode,
            };
        });
        // 排序，方便后续更快获取最大值和最小值
        mapData = mapData.sort(function (a, b) {
            return b.value - a.value;
        });
        initEcharts(mapData);
    };

    /**
     * @description 渲染echarts
     * @param {array} mapData 图表数据 [{name: string,value: number,cityCode:number}]
     */
    const initEcharts =(mapData) => {
        // 获取最小值
        var min = mapData[mapData.length - 1].value;
        // 获取最大值
        var max = mapData[0].value;
        // length === 1 时默认本身为最大值，最小值取 0
        if (mapData.length === 1) {
            min = 0;
        }
        // 重绘图表时，把之前已经渲染好的图表清空,避免报错
        if (mapChart.value) {
            mapChart.value.dispose();
        }
        // 创建一个 ECharts 实例
        mapChart.value = echarts.init(chartRef.value);
        //注册可用的地图，只在 geo 组件或者 map 图表类型中使用
        if (parentInfo.value.length === 1) {
            echarts.registerMap("china", geoJson.value); //注册
        } else {
            echarts.registerMap("map", geoJson.value); //注册
        }

        // 设置图表实例的配置项以及数据
        mapChart.value.setOption({
            geo: {
                map: parentInfo.value.length === 1 ? "china" : "map", //使用 registerMap 注册的地图名称 ,必须和 registerMap 注册的一致
                show:false,//不显示地图的坐标系，但是其坐标系的功能依旧存在，可大大提高移动缩放的体验感，不会很卡顿
                roam:true,//开启缩放平移
            },
            animationDurationUpdate:0,//地图移动的时候，渲染的点跟着移动，但是会有延迟，设置为0，则没有延迟
            // 背景色
            backgroundColor: "#03213D",
            // 提示框
            tooltip: {
                trigger: "item", //触发类型,数据项图形触发
                formatter: (p) => {
                    //提示框浮层内容格式器，支持字符串模板和回调函数两种形式。
                    let val = p.value;
                    if (!val) {
                        val = 0;
                    }
                    let txtCon = p.name + ":" + val.toFixed(2);
                    return txtCon;
                },
            },
            // 标题
            title: {
                show: true,
                left: "center",
                top: "15",
                text: parentInfo.value[parentInfo.value.length - 1].cityName,
                textStyle: {
                    color: "rgba(147, 235, 248, .8)",
                    fontSize: 16,
                },
            },
            series: [{
                name: "地图分布",
                type: "map", //地图
                map: parentInfo.value.length === 1 ? "china" : "map", //使用 registerMap 注册的地图名称 ,必须和 registerMap 注册的一致
                animationDurationUpdate:0,//实现缩放、拖动同步且不卡顿
                roam: true, //是否开启鼠标缩放和平移漫游
                zoom: 1, //当前视角的缩放比例
                aspectScale:1,  // 地图的长宽比
                data: mapData,
                label: {
                    //图形上的文本标签
                    show: true,
                    color: "rgb(249, 249, 249)", //省份标签字体颜色
                    formatter: (p) => {
                        switch (p.name) {
                            case "内蒙古自治区":
                                p.name = "内蒙古";
                                break;
                            case "西藏自治区":
                                p.name = "西藏";
                                break;
                            case "新疆维吾尔自治区":
                                p.name = "新疆";
                                break;
                            case "宁夏回族自治区":
                                p.name = "宁夏";
                                break;
                            case "广西壮族自治区":
                                p.name = "广西";
                                break;
                            case "香港特别行政区":
                                p.name = "香港";
                                break;
                            case "澳门特别行政区":
                                p.name = "澳门";
                                break;
                            default:
                                break;
                        }
                        return p.name;
                    },
                },
                itemStyle: {
                    //地图区域的多边形 图形样式
                    areaColor: "#24CFF4",
                    borderColor: "#53D9FF",
                    borderWidth: 1.3,
                    shadowBlur: 10,
                    shadowColor: "rgb(58,115,192)",
                    shadowOffsetX: 7,
                    shadowOffsetY: 6,
                },
                emphasis: {
                    //高亮状态下的多边形和标签样式
                    label: {
                        show: true,
                        color: "#f75a00",
                    },
                    itemStyle: {
                        areaColor: "#8dd7fc",
                        borderWidth: 1.6,
                        shadowBlur: 25,
                    },
                },
            },
            ],
        });
        // 根据页面大小自动响应图表大小
        window.addEventListener("resize", function () {
            mapChart.value.resize();
        });
        // 解绑鼠标点击事件处理函数，以防重复点击
        mapChart.value.off("click");
        // 绑定鼠标点击事件处理函数
        mapChart.value.on("click", (params) => {
            if (parentInfo.value[parentInfo.value.length - 1].code == params.data.cityCode) {
                return;
            }
            let data = params.data;
            parentInfo.value.push({
                cityName: data.name,
                code: data.cityCode,
            });
            getGeoJson(data.cityCode);
        });

    };

    /**
     * @description 选择切换市县
     * @param {object} val
     * @param {number} index
     */
    const chooseArea =(val, index) => {
        // 如果点击自己，直接return
        if (parentInfo.value.length === index + 1) {
            return;
        }
        //从aparentInfo索引为 index + 1 的位置开始其后面的都删除，返回的是移除的所有元素所构成的新数组
        parentInfo.value.splice(index + 1);
        getGeoJson(parentInfo.value[parentInfo.value.length - 1].code);
    };




    onMounted(() => {
        getGeoJson(100000)
    });

</script>

<style lang="scss" scoped>
    .content{
        width: 100%;
        height: 100%;
    }
    .content-title{
        position: absolute;
        top: 50px;
        color: #FFFFFF;
    }
    .chart-div{
        width: 100%;
        height: calc(#{$web-height} - #{$web-left-title-height} + 20px);
    }
    .mapChoose {
        position: absolute;
        top: 95px;
        color: #eee;

    .button {
        position: relative;
        padding: 8px 15px;
        border: none;
        background-color: transparent;
        cursor: pointer;
        outline: none;
        font-size: 14px;
    }

    .button.type1 {
        color: rgba(147, 235, 248, 0.8);
    }
    }
</style>